package com.hqyj.springCloundAccount.server.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hqyj.account.entity.User;
import com.hqyj.account.entity.UserRole;
import com.hqyj.account.vo.UserVo;
import com.hqyj.commom.vo.Result;
import com.hqyj.commom.vo.Search;
import com.hqyj.springCloundAccount.dao.UserDao2;
import com.hqyj.springCloundAccount.dao.UserRoleDao2;
import com.hqyj.springCloundAccount.server.TestFeignClient;
import com.hqyj.springCloundAccount.server.UserService;
import com.hqyj.springCloundAccount.utils.MD5Util;
import com.hqyj.test.entity.City;
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.vavr.control.Try;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Service
public class UserServiceImpl implements UserService {

    public final static Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);



    @Autowired
    private UserDao2 userDao2;
      @Autowired
    private UserRoleDao2 userRoleDao2;
      @Autowired
      private RestTemplate restTemplate;
      @Autowired
      private TestFeignClient testFeignClient;




    @Override
    public User getUserByUserNameAndPassword(String userName, String Password) {
       return userDao2.getUserByUserNameAndPassword(userName, MD5Util.getMD5(Password));
    }

    @Override
    @Transactional
    public Result<User> login(User user) {





        User temp = userDao2.getUserByUserNameAndPassword(user.getUserName(), MD5Util.getMD5(user.getPassword()));
        if (temp == null){
            return new Result<User>(Result.ResultStatus.FAILD.code, "用户名或密码错误!");
        }
        return new Result<User>(Result.ResultStatus.SUCCESS.code, "登录成功!",temp);
    }

    @Override
    public void logout() {



    }

    @Override
    @Transactional
    public Result<User> updateUser(User user) {
        List<User> users = Optional.ofNullable(userDao2.getUserByUserName(user.getUserName())).orElse(Collections.emptyList());
        if (users.stream().filter(item -> item.getId() != user.getId()).count() > 0){
            return new Result<User>(Result.ResultStatus.FAILD.code, "用户名已存在!");
        }
        user.setUpdateDate(LocalDateTime.now());

        userDao2.updateUser(user);
        if (user.getRoles() != null && !user.getRoles().isEmpty()){
            userRoleDao2.deleteUserRoleByUserId(user.getId());
            user.getRoles().stream().forEach(item -> {
                UserRole userRole = new UserRole();
                userRole.setCreateDate(LocalDateTime.now());
                userRole.setUpdateDate(LocalDateTime.now());
                userRole.setUserId(user.getId());
                userRole.setRoleId(item.getId());
                userRoleDao2.addUserRole(userRole);
            });
        }
        return new Result<User>(Result.ResultStatus.SUCCESS.code, "用户修改成功!",user);
    }

    @Override
    public User getUserById(int id) {

        return userDao2.getUserAndUserRoleById(id);
    }

    @Override
    public User getUserByUserName(String userName) {
        List<User> users =Optional.ofNullable( userDao2.getUserByUserName(userName)).orElse(Collections.emptyList());

        return users.isEmpty() ? null : users.get(0);


    }

    @Override
    @Transactional
    public Result<Object> deleteUserById(int id) {
        userDao2.deleteUserById(id);
        userRoleDao2.deleteUserRoleByUserId(id);
        return new Result<Object>(Result
                .ResultStatus
                .SUCCESS.code, "用户删除成功!");
    }

    @Override
    public PageInfo<User> getUserBySearch(Search search) {
        search.init();
        PageHelper.startPage(search.getCurrentPage(),search.getPageSize());
        return new PageInfo<User>(Optional
                .ofNullable(userDao2.getUsersBySearchVo(search))
                .orElse(Collections.emptyList()));

    }

    @Override
    public List<User> getUserByKeyword(String keyword) {
        Search search = new Search();
        search.setKeyword(keyword);
        search.init();

        return Optional.ofNullable(userDao2.getUsersBySearchVo(search))
                .orElse(Collections.emptyList());
    }


    @Override
    public UserVo getUserVoByUserIdAndCityId(int userId, int cityId) {
        UserVo userVo = new UserVo();
        User user = userDao2.getUserById(userId);
        BeanUtils.copyProperties(user,userVo);
//        City city = restTemplate.getForObject(
//                "http://client-test/api/city/{cityId}",City.class,cityId
//        );
//        userVo.setCity(city);

        CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
                .failureRateThreshold(50)
                .waitDurationInOpenState(Duration.ofMillis(1000))
                .build();
        CircuitBreaker circuitBreaker = CircuitBreaker.of("circuitBreakerPloy", circuitBreakerConfig);
        Try<City> circuitBreakerSupplier = Try.ofSupplier(CircuitBreaker.decorateSupplier(
                circuitBreaker,
                () -> testFeignClient.getCityByCityId(cityId)
        )).recover(Exception.class, new City());
        userVo.setCity(circuitBreakerSupplier.get());
        return userVo;
    }


    @Override
    @Transactional
    public Result<User> addUser(User user) {
      if (StringUtils.isBlank(user.getUserName()) || StringUtils.isBlank(user.getPassword())){
          return new Result<User>(Result.ResultStatus.FAILD.code, "用户名或密码为空!");
      }
        List<User> users = Optional.ofNullable(userDao2.getUserByUserName(user.getUserName()))
                .orElse(Collections.emptyList());
      if (users.size() > 0){
          return new Result<User>(Result.ResultStatus.FAILD.code, "用户名已存在!");
      }
      user.setCreateDate(LocalDateTime.now());
      user.setUpdateDate(LocalDateTime.now());
      user.setPassword(MD5Util.getMD5(user.getPassword()));
      userDao2.addUser(user);
      if (user.getRoles() != null){
          user.getRoles().stream().forEach(item -> {
              UserRole userRole = new UserRole();
              userRole.setCreateDate(LocalDateTime.now());
              userRole.setUpdateDate(LocalDateTime.now());
              userRole.setUserId(user.getId());
              userRole.setRoleId(item.getId());
              userRoleDao2.addUserRole(userRole);
          });
      }
       return new Result<User>(Result.ResultStatus.SUCCESS.code, "用户添加成功!",user);


    }




}
